/**
 *                            License
 * THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS  
 * CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). 
 * THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.  
 * ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR  
 * COPYRIGHT LAW IS PROHIBITED.
 * 
 * BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND  
 * AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE  
 * MAY BE CONSIDERED TO BE A CONTRACT,
 * THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED 
 * HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
 * 
 */
package com.lineage.server.model.skill.executor;

import static com.lineage.server.model.skill.L1SkillId.ABSOLUTE_BARRIER;
import static com.lineage.server.model.skill.L1SkillId.ADVANCE_SPIRIT;
import static com.lineage.server.model.skill.L1SkillId.AWAKEN_ANTHARAS;
import static com.lineage.server.model.skill.L1SkillId.AWAKEN_FAFURION;
import static com.lineage.server.model.skill.L1SkillId.AWAKEN_VALAKAS;
import static com.lineage.server.model.skill.L1SkillId.BLESSED_ARMOR;
import static com.lineage.server.model.skill.L1SkillId.COOKING_BEGIN;
import static com.lineage.server.model.skill.L1SkillId.COOKING_END;
import static com.lineage.server.model.skill.L1SkillId.COOKING_WONDER_DRUG;
import static com.lineage.server.model.skill.L1SkillId.COUNTER_BARRIER;
import static com.lineage.server.model.skill.L1SkillId.ENCHANT_WEAPON;
import static com.lineage.server.model.skill.L1SkillId.REDUCTION_ARMOR;
import static com.lineage.server.model.skill.L1SkillId.SHADOW_FANG;
import static com.lineage.server.model.skill.L1SkillId.SHOCK_STUN;
import static com.lineage.server.model.skill.L1SkillId.SKILLS_BEGIN;
import static com.lineage.server.model.skill.L1SkillId.SKILLS_END;
import static com.lineage.server.model.skill.L1SkillId.SOLID_CARRIAGE;
import static com.lineage.server.model.skill.L1SkillId.STATUS_BEGIN;
import static com.lineage.server.model.skill.L1SkillId.STATUS_CHAT_PROHIBITED;
import static com.lineage.server.model.skill.L1SkillId.STATUS_END;
import static com.lineage.server.model.skill.L1SkillId.STATUS_FREEZE;

import com.lineage.server.codes.ActionCodes;
import com.lineage.server.model.L1Character;
import com.lineage.server.model.L1PinkName;
import com.lineage.server.model.L1PolyMorph;
import com.lineage.server.model.Instance.L1NpcInstance;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.model.skill.L1SkillExecutor;
import com.lineage.server.packetserver.S_ChangeName;
import com.lineage.server.packetserver.S_CharVisualUpdate;
import com.lineage.server.packetserver.S_DoActionShop;
import com.lineage.server.packetserver.S_NpcChangeShape;
import com.lineage.server.packetserver.S_SkillBrave;
import com.lineage.server.packetserver.S_SkillHaste;

/**
 * Class <code>CancelMagic</code> 法师魔法:魔法相消术 (40/0/2).
 * 除目标身上所有的魔法效果
 * 
 * @author jrwz
 * @version 2012-7-24下午08:44:43
 * @see com.lineage.server.model.skill.executor
 * @since JDK1.7
 */
public final class CancelMagic extends L1SkillExecutor {

    /**
     * 取得实例.
     * 
     * @return 实例
     */
    public static L1SkillExecutor get() {
        return new CancelMagic();
    }

    /**
     * 是否不可取消.
     * 
     * @param skillNum
     *            - 技能编号
     * @return 技能编号
     */
    private static boolean isNotCancelable(final int skillNum) {
        return (skillNum == ENCHANT_WEAPON) || (skillNum == BLESSED_ARMOR)
                || (skillNum == ABSOLUTE_BARRIER)
                || (skillNum == ADVANCE_SPIRIT) || (skillNum == SHOCK_STUN)
                || (skillNum == SHADOW_FANG) || (skillNum == REDUCTION_ARMOR)
                || (skillNum == SOLID_CARRIAGE)
                || (skillNum == COUNTER_BARRIER)
                || (skillNum == AWAKEN_ANTHARAS)
                || (skillNum == AWAKEN_FAFURION)
                || (skillNum == AWAKEN_VALAKAS)
                || (skillNum == COOKING_WONDER_DRUG);
    }

    /** 法师魔法:魔法相消术 (40/0/2). */
    private CancelMagic() {
    }

    @Override
    public void execute(final L1Character user, final L1Character cha,
            final L1Character target, final int targetID, final int skillId,
            final int getBuffIconDuration) {
        L1PcInstance player = null;
        if (user instanceof L1PcInstance) {
            final L1PcInstance pc = (L1PcInstance) user;
            player = pc;
        }
        if (cha instanceof L1NpcInstance) {
            final L1NpcInstance npc = (L1NpcInstance) cha;
            final int npcId = npc.getNpcTemplate().get_npcId();
            if (npcId == 71092) { // 调查员
                if (npc.getGfxId() == npc.getTempCharGfx()) {
                    npc.setTempCharGfx(1314);
                    npc.broadcastPacket(new S_NpcChangeShape(npc.getId(), 1314,
                            npc.getLawful(), npc.getStatus()));
                    return;
                }
                return;
            }
            if (npcId == 45640) { // 独角兽
                if (npc.getGfxId() == npc.getTempCharGfx()) {
                    npc.setCurrentHp(npc.getMaxHp());
                    npc.setTempCharGfx(2332);
                    npc.broadcastPacket(new S_NpcChangeShape(npc.getId(), 2332,
                            npc.getLawful(), npc.getStatus()));
                    npc.setName("$2103");
                    npc.setNameId("$2103");
                    npc.broadcastPacket(new S_ChangeName(npc.getId(), "$2103"));
                } else if (npc.getTempCharGfx() == 2332) {
                    npc.setCurrentHp(npc.getMaxHp());
                    npc.setTempCharGfx(2755);
                    npc.broadcastPacket(new S_NpcChangeShape(npc.getId(), 2755,
                            npc.getLawful(), npc.getStatus()));
                    npc.setName("$2488");
                    npc.setNameId("$2488");
                    npc.broadcastPacket(new S_ChangeName(npc.getId(), "$2488"));
                }
            }
            if (npcId == 81209) { // 罗伊
                if (npc.getGfxId() == npc.getTempCharGfx()) {
                    npc.setTempCharGfx(4310);
                    npc.broadcastPacket(new S_NpcChangeShape(npc.getId(), 4310,
                            npc.getLawful(), npc.getStatus()));
                    return;
                }
                return;
            }
            if (npcId == 81352) { // 欧姆民兵
                if (npc.getGfxId() == npc.getTempCharGfx()) {
                    npc.setTempCharGfx(148);
                    npc.broadcastPacket(new S_NpcChangeShape(npc.getId(), 148,
                            npc.getLawful(), npc.getStatus()));
                    npc.setName("$6068");
                    npc.setNameId("$6068");
                    npc.broadcastPacket(new S_ChangeName(npc.getId(), "$6068"));
                }
            }
        }
        if ((player != null) && player.isInvisble()) {
            player.delInvis();
        }
        if (cha instanceof L1NpcInstance) {
            final L1NpcInstance npc = (L1NpcInstance) cha;
            npc.setMoveSpeed(0);
            npc.setBraveSpeed(0);
            npc.broadcastPacket(new S_SkillHaste(cha.getId(), 0, 0));
            npc.broadcastPacket(new S_SkillBrave(cha.getId(), 0, 0));
            npc.setWeaponBreaked(false);
            npc.setParalyzed(false);
            npc.setParalysisTime(0);
        }

        // 清除技能
        for (int skillNum = SKILLS_BEGIN; skillNum <= SKILLS_END; skillNum++) {
            if (isNotCancelable(skillNum) && !cha.isDead()) {
                continue;
            }
            cha.removeSkillEffect(skillNum);
        }

        // 解除异常的强化状态
        cha.curePoison();
        cha.cureParalaysis();
        for (int skillNum = STATUS_BEGIN; skillNum <= STATUS_END; skillNum++) {
            if (skillNum == STATUS_CHAT_PROHIBITED) { // 禁言
                continue;
            }
            cha.removeSkillEffect(skillNum);
        }

        if (cha instanceof L1PcInstance) {
        }

        // 解除料理状态
        for (int skillNum = COOKING_BEGIN; skillNum <= COOKING_END; skillNum++) {
            if (isNotCancelable(skillNum)) {
                continue;
            }
            cha.removeSkillEffect(skillNum);
        }

        if (cha instanceof L1PcInstance) {
            final L1PcInstance pc = (L1PcInstance) cha;

            // 解除道具装备变身
            L1PolyMorph.undoPoly(pc);
            pc.sendPackets(new S_CharVisualUpdate(pc));
            pc.broadcastPacket(new S_CharVisualUpdate(pc));

            // 解除装备道具时关联的任何技能类
            if (pc.getHasteItemEquipped() > 0) {
                pc.setMoveSpeed(0);
                pc.sendPackets(new S_SkillHaste(pc.getId(), 0, 0));
                pc.broadcastPacket(new S_SkillHaste(pc.getId(), 0, 0));
            }
        }
        cha.removeSkillEffect(STATUS_FREEZE); // Freeze解除
        if (cha instanceof L1PcInstance) {
            final L1PcInstance pc = (L1PcInstance) cha;
            pc.sendPackets(new S_CharVisualUpdate(pc));
            pc.broadcastPacket(new S_CharVisualUpdate(pc));
            if (pc.isPrivateShop()) {
                pc.sendPackets(new S_DoActionShop(pc.getId(),
                        ActionCodes.ACTION_SHOP, pc.getShopChat()));
                pc.broadcastPacket(new S_DoActionShop(pc.getId(),
                        ActionCodes.ACTION_SHOP, pc.getShopChat()));
            }
            if (user instanceof L1PcInstance) {
                L1PinkName.onAction(pc, user);
            }
        }
    }

    @Override
    public void stop(final L1Character cha, final int skillId) {
        // TODO Auto-generated method stub
    }
}
